@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)

import kotlinx.cinterop.*
import platform.posix.*

fun main(args: Array<String>) {
    val n = if (args.isNotEmpty()) args[0].toIntOrNull() ?: 10 else 10
    if (n < 0 || n > 12) {
        println("Invalid input (n must be between 0 and 12)")
        return
    }

    val (checkSum, maxFlips) = fannkuch(n)
    println("$checkSum\nPfannkuchen($n) = $maxFlips")
}

private fun fannkuch(n: Int): Pair<Int, Int> {
    if (n <= 1) {
        return 0 to 0
    }

    // 计算阶乘表（与Java完全一致）
    val fact = IntArray(n + 1)
    fact[0] = 1
    for (i in 1..n) {
        fact[i] = fact[i - 1] * i
    }
    val totalPerms = fact[n]

    val p = IntArray(n)      // 当前排列
    val pp = IntArray(n)     // 翻转副本
    val count = IntArray(n)  // 计数数组

    // 初始化第一个排列（与Java完全一致）
    for (i in 0 until n) {
        p[i] = i
    }

    var maxFlips = 0
    var checkSum = 0

    // 遍历所有排列（严格同步Java的循环逻辑）
    for (idx in 0 until totalPerms) {
        // 计算当前排列的翻转次数
        if (p[0] != 0) {
            // 数组复制逻辑与Java的System.arraycopy完全对齐
            for (i in 0 until n) {
                pp[i] = p[i]
            }
            var flips = 1
            var first = pp[0]

            // 翻转逻辑严格同步Java
            while (pp[first] != 0) {
                flips++
                var lo = 1
                var hi = first - 1
                while (lo < hi) {
                    // 交换逻辑完全一致
                    val temp = pp[lo]
                    pp[lo] = pp[hi]
                    pp[hi] = temp
                    lo++
                    hi--
                }
                // 更新first的逻辑与Java完全相同
                val temp = pp[first]
                pp[first] = first
                first = temp
            }

            if (flips > maxFlips) {
                maxFlips = flips
            }
            // 校验和计算严格遵循Java的奇偶逻辑
            checkSum += if (idx % 2 == 0) flips else -flips
        }

        // 生成下一个排列（核心逻辑与Java逐行对齐）
        var i = 1
        count[i]++
        while (count[i] > i) {
            count[i] = 0
            i++
            if (i >= n) break
            count[i]++
        }
        if (i >= n) break  // 退出条件与Java完全一致

        // 旋转前缀逻辑严格同步Java
        val first = p[0]
        for (j in 0 until i) {
            p[j] = p[j + 1]
        }
        p[i] = first
    }

    return checkSum to maxFlips
}
